package com.adnaan.backend.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.adnaan.backend.entity.Order;
import com.adnaan.backend.entity.RecognizeRecord;
import com.adnaan.backend.entity.SysUser;
import com.adnaan.backend.mapper.*;
import com.adnaan.backend.service.DashboardService;
import com.adnaan.backend.utils.AuthUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.*;

@Service
public class DashboardServiceImpl implements DashboardService {

    @Resource
    private MedicinalMapper medicinalMapper;
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private SysUserMapper userMapper;
    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private RecognizeMapper recognizeRecordMapper;
    @Resource
    private ViewHistoryMapper viewHistoryMapper;
    @Resource
    private UserLikesMapper userLikesMapper;
    @Resource
    private UserCollectMapper userCollectMapper;

    @Override
    public Map<String, Object> getStatistics() {
        Map<String, Object> result = new HashMap<>();
        // 获取总体统计数据
        result.put("totalMedicinals", medicinalMapper.selectCount(null));
        result.put("totalOrders", orderMapper.selectCount(null));
        result.put("totalUsers", userMapper.selectCount(null));
        result.put("totalArticles", articleMapper.selectCount(null));
        return result;
    }

    @Override
    public Map<String, Object> getOrderTrend(LocalDate startDate, LocalDate endDate) {
        Map<String, Object> result = new HashMap<>();
        List<String> dates = new ArrayList<>();
        List<Long> counts = new ArrayList<>();

        // 计算日期范围内的每一天
        long daysBetween = ChronoUnit.DAYS.between(startDate, endDate.plusDays(1));
        for (int i = 0; i < daysBetween; i++) {
            LocalDate currentDate = startDate.plusDays(i);
            dates.add(currentDate.toString());

            // 查询当天的订单数量
            LocalDateTime dayStart = LocalDateTime.of(currentDate, LocalTime.MIN);
            LocalDateTime dayEnd = LocalDateTime.of(currentDate, LocalTime.MAX);

            LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<Order>()
                    .between(Order::getCreateTime, dayStart, dayEnd);

            // 如果不是管理员，只查询当前供应商的订单
            if (!AuthUtils.isAdmin()) {
                queryWrapper.eq(Order::getSupplierId, StpUtil.getLoginIdAsLong());
            }

            long count = orderMapper.selectCount(queryWrapper);
            counts.add(count);
        }

        result.put("dates", dates);
        result.put("counts", counts);
        return result;
    }

    @Override
    public Map<String, Object> getUserActivity(LocalDate startDate, LocalDate endDate) {
        Map<String, Object> result = new HashMap<>();
        List<String> dates = new ArrayList<>();
        List<Long> counts = new ArrayList<>();

        // 计算日期范围内的每一天的活跃用户数
        long daysBetween = ChronoUnit.DAYS.between(startDate, endDate.plusDays(1));
        for (int i = 0; i < daysBetween; i++) {
            LocalDate currentDate = startDate.plusDays(i);
            dates.add(currentDate.toString());

            LocalDateTime dayStart = LocalDateTime.of(currentDate, LocalTime.MIN);
            LocalDateTime dayEnd = LocalDateTime.of(currentDate, LocalTime.MAX);

            // 统计当天有操作的用户数（基于最后登录时间）
            long count = userMapper.selectCount(new LambdaQueryWrapper<SysUser>()
                    .between(SysUser::getLastLoginTime, dayStart, dayEnd));
            counts.add(count);
        }

        result.put("dates", dates);
        result.put("counts", counts);
        return result;
    }

    @Override
    public Map<String, Object> getRecognizeStats() {
        Map<String, Object> result = new HashMap<>();

        // 统计识别成功和失败的数量
        long successCount = recognizeRecordMapper.selectCount(
                new LambdaQueryWrapper<RecognizeRecord>()
                        .eq(RecognizeRecord::getStatus, 1));

        long failCount = recognizeRecordMapper.selectCount(
                new LambdaQueryWrapper<RecognizeRecord>()
                        .eq(RecognizeRecord::getStatus, 0));

        result.put("success", successCount);
        result.put("fail", failCount);
        return result;
    }

    @Override
    public Map<String, Object> getArticleStats(String timeRange) {
        Map<String, Object> result = new HashMap<>();
        LocalDate endDate = LocalDate.now();
        LocalDate startDate;

        // 根据时间范围确定起始日期
        switch (timeRange) {
            case "week":
                startDate = endDate.minusWeeks(1);
                break;
            case "month":
                startDate = endDate.minusMonths(1);
                break;
            case "year":
                startDate = endDate.minusYears(1);
                break;
            default:
                throw new IllegalArgumentException("Invalid time range");
        }

        // 生成日期列表
        List<String> dates = new ArrayList<>();
        long daysBetween = ChronoUnit.DAYS.between(startDate, endDate.plusDays(1));
        for (int i = 0; i < daysBetween; i++) {
            dates.add(startDate.plusDays(i).toString());
        }

        // 初始化统计数组
        List<Integer> views = new ArrayList<>(Collections.nCopies(dates.size(), 0));
        List<Integer> likes = new ArrayList<>(Collections.nCopies(dates.size(), 0));
        List<Integer> collects = new ArrayList<>(Collections.nCopies(dates.size(), 0));

        // 查询时间范围
        LocalDateTime startTime = LocalDateTime.of(startDate, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(endDate, LocalTime.MAX);

        // 获取各项统计数据
        Map<String, Integer> viewsMap = new HashMap<>();
        viewHistoryMapper.countGroupByDate(startTime, endTime).forEach(map ->
                viewsMap.put(map.get("date").toString(), ((Number) map.get("count")).intValue()));

        Map<String, Integer> likesMap = new HashMap<>();
        userLikesMapper.countGroupByDate(startTime, endTime).forEach(map ->
                likesMap.put(map.get("date").toString(), ((Number) map.get("count")).intValue()));

        Map<String, Integer> collectsMap = new HashMap<>();
        userCollectMapper.countGroupByDate(startTime, endTime).forEach(map ->
                collectsMap.put(map.get("date").toString(), ((Number) map.get("count")).intValue()));

        // 填充数据
        for (int i = 0; i < dates.size(); i++) {
            String date = dates.get(i);
            views.set(i, viewsMap.getOrDefault(date, 0));
            likes.set(i, likesMap.getOrDefault(date, 0));
            collects.set(i, collectsMap.getOrDefault(date, 0));
        }

        result.put("dates", dates);
        result.put("views", views);
        result.put("likes", likes);
        result.put("collects", collects);
        return result;
    }
}